package erlwitch.project;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Date;
import java.util.Enumeration;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

import erlwitch.project.fileFilters.ArchiveRegExpFilter;

public class HierarchyBuilder {

	private JTree tree;
	private DefaultMutableTreeNode rootNode;
	private File rootDir;

	public HierarchyBuilder(File rootDir) {
		this.rootDir = rootDir.getAbsoluteFile();
		rootNode = new DefaultMutableTreeNode("root");
		tree = new JTree(rootNode);
	}
	
	/**
	 * Interpreta la regla y modifica la su estructura interna. 
	 * @param line
	 */
	public void addRule(String inputRule) {
		String rule = inputRule.trim();
		int firstSpace = rule.indexOf(' ');
		int lastSpace = rule.lastIndexOf(' ');
		if (firstSpace != -1 && lastSpace != -1 && firstSpace != lastSpace) {
			String command = rule.substring(0, firstSpace);
			String path = rule.substring(firstSpace, lastSpace).trim(); //podrian haber mas espacios
			String regExp = rule.substring(lastSpace+1, rule.length());
			File dir = (!path.equals(".")) ? new File(rootDir, path) : rootDir;
			if (dir.exists() && dir.isDirectory()) {
				if (command.equalsIgnoreCase("Add")) {
					add(dir, regExp);
				}
				else if (command.equalsIgnoreCase("Remove")) {
					
				} else if (command.equalsIgnoreCase("AddRec")) {
					
				} else if (command.equalsIgnoreCase("RemoveRec")) {
					
				} else {
					//FIXME Explotar?
				}
			} else {
				//FIXME explotar?
			}
		}
	}
	
	public void add(File dir, String regExp) {
		DefaultMutableTreeNode dirNode = addMissingDirectories(dir);
		FilenameFilter filter = new ArchiveRegExpFilter(regExp);
		addChilds(dirNode, dir, filter);
	}

	private DefaultMutableTreeNode addMissingDirectories(File dir) {
		if (!dir.equals(rootDir)) {
			DefaultMutableTreeNode parentNode = addMissingDirectories(dir.getParentFile());
			Enumeration children = parentNode.children();
			boolean found = false;
			DefaultMutableTreeNode childNode = null;
			while (children.hasMoreElements() && !found) {
				childNode = (DefaultMutableTreeNode)children.nextElement();
				found = childNode.getUserObject().equals(dir.getName());
			}
			if (!found) {
				childNode = new DefaultMutableTreeNode(dir.getName());
				parentNode.add(childNode);
			}
			return childNode;
		} else {
			return rootNode;		
		}
	}

	public void addRec(String dir, String filter) {
		// TODO
	}

	public void remove(String dir, String filter) {
		// TODO
	}

	public void removeRec(String dir, String filter) {
		// TODO
	}

	public JTree getTree() {
		return tree;
	}
	
	/**
	 * Por ahora esta funcion es recursiva (para incluir subdirectoros) a pesar que solo es llamada 
	 * con un ArchiveRegExpFilter.
	 * @param node Nodo que representa al parametro dir
	 * @param dir
	 * @param filter
	 */
	private void addChilds(DefaultMutableTreeNode node, File dir, FilenameFilter filter) {
		File[] childFiles = dir.listFiles(filter);
		for (File childFile : childFiles) {
			SourceFile sf = new SourceFile();
			sf.setFile(childFile.getAbsoluteFile());
			sf.setPath(childFile.getAbsolutePath());
			//TODO: ver si hay que parsear aca
			sf.setLastParsed(new Date(0));

			DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(sf);
			if (childFile.isDirectory()) {
				addChilds(childNode, childFile, filter);
			}
			node.add(childNode);
		}
	}

	private DefaultMutableTreeNode getSourceFileRec(File file) {
		if (file == null) {
			return null;
		} else if (!file.equals(rootDir)) {
			DefaultMutableTreeNode parentNode = getSourceFileRec(file.getParentFile());
			if (parentNode == null) {
				return null;
			}
			Enumeration children = parentNode.children();
			boolean found = false;
			DefaultMutableTreeNode childNode = null;
			while (children.hasMoreElements() && !found) {
				childNode = (DefaultMutableTreeNode)children.nextElement();
				SourceFile childFile = (SourceFile)childNode.getUserObject();
				found =  childFile.getFile().equals(file);
			}
			if (!found) {
				return null;
			}
			return childNode;
		} else {
			return rootNode;		
		}
	}
	
	public SourceFile getSourceFile(String path) {
		File f = new File(path).getAbsoluteFile();
		DefaultMutableTreeNode node = getSourceFileRec(f);
		if (node == null) {
			return null;
		} else {
			return (SourceFile)node.getUserObject();
		}
	}
}
